package com.cincc.cinccimdemo.common;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.cincc.cinccimdemo.R;
import com.cincc.cinccimdemo.common.callback.OnConversationInfoUpdateListener;
import com.cincc.cinccimdemo.common.callback.OnConversationListRefreshListener;
import com.cincc.cinccimdemo.common.callback.OnConversationRefreshListener;
import com.cincc.cinccimdemo.common.record.VoiceInfo;
import com.cincc.cinccimdemo.model.CardInfo;
import com.cincc.cinccimdemo.model.FriendInfoUI;
import com.cincc.cinccimdemo.model.MessageInfo;
import com.cincc.cinccimdemo.model.MessageInfoUI;
import com.cincc.im.model.dbmodel.GroupMemberInfo;
import com.cincc.im.model.dbmodel.GroupMessageInfo;
import com.cincc.im.model.dbmodel.MessageModel;
import com.cincc.im.model.dbmodel.P2PMessageInfo;
import com.cincc.im.model.dbmodel.P2PMessageModel;
import com.cincc.im.model.dbmodel.SequenceInfo;
import com.cincc.im.model.enums.ImSendType;
import com.cincc.im.model.enums.MessageType;
import com.cincc.im.model.enums.SendStatus;
import com.cincc.im.model.message.ImAudioMessage;
import com.cincc.im.model.message.ImFileMessage;
import com.cincc.im.model.message.ImImageMessage;
import com.cincc.im.model.message.ImMessage;
import com.cincc.im.model.message.ImSequenceMessage;
import com.cincc.im.model.message.ImTextMessage;
import com.cincc.im.model.message.ImVideoMessage;
import com.cincc.im.util.DateTimeUtil;
import com.cincc.im.util.IMUtil;
import com.cincc.im.util.ImManager;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

public class MyUtils {
    private static final String TAG = "MyUtils";
    static List<OnConversationListRefreshListener> onConversationListRefreshListenerList = new ArrayList<>();
    static List<OnConversationRefreshListener> onConversationRefreshListeners = new ArrayList<>();
    static List<OnConversationInfoUpdateListener> onConversationInfoUpdateListeners = new ArrayList<>();

    public static void showToast(Context c, String msg) {
        Toast.makeText(c, msg, Toast.LENGTH_SHORT).show();
    }

    /**
     * 得到应用程序的包名
     *
     * @return 包名
     */
    public static String getPackageName() {
        return ImManager.getInstance().getApplicationContext().getPackageName();
    }

    /**
     * 去中横线 小写
     *
     * @return uuid
     */
    public static String getUUID() {
        return UUID.randomUUID().toString().replace("-", "").toLowerCase();
    }

    /**
     * 警告框
     */
    public static void showWarn(Context context, int img, int msg) {
        Toast toast = new Toast(context);
        View view = LayoutInflater.from(context).inflate(R.layout.warn_popup, null);
        ImageView imageView = view.findViewById(R.id.warn_image);
        TextView textView = view.findViewById(R.id.warn_text);
        imageView.setImageResource(img);
        textView.setText(msg);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.setView(view);
        toast.setDuration(Toast.LENGTH_SHORT);
        toast.show();
    }

    /**
     * 判断是否是网络地址
     *
     * @param url 地址
     * @return 结果
     */
    public static boolean isNetUrl(String url) {
        boolean result = false;
        if (url != null) {
            if (url.toLowerCase().startsWith("http") || url.toLowerCase().startsWith("https")) {
                result = true;
            }
        }
        return result;
    }

    /**
     * 得到主线程Handler
     *
     * @return
     */
    public static Handler getMainThreadHandler() {
        return ImManager.getInstance().getMainHandler();
    }

    /**
     * 安全的执行一个任务
     *
     * @param task
     */
    public static void postTaskSafely(Runnable task) {
        // 如果当前线程是主线程
        if (Looper.myLooper() == Looper.getMainLooper()) {
            task.run();
        } else {
            // 如果当前线程不是主线程
            getMainThreadHandler().post(task);
        }
    }

    /**
     * 获取表情包列表
     *
     * @param context 上下文
     * @return
     */
    public static String[] getEmojiList(Context context) {
        String content = FileUtils.getFromAssets(context, "emoji_img");
        return content.split(",");
    }

    /**
     * 获取表情包名字列表
     *
     * @param context 上下文
     * @return
     */
    public static String[] getEmojiTextList(Context context) {
        String content = FileUtils.getFromAssets(context, "emoji_text");
        return content.split(",");
    }

    /**
     * 消息时间跟现在间隔小于规定时间才可以撤回
     *
     * @param messageInfoUI 消息对象
     * @return 结果
     */
    public static Boolean isCanRecall(MessageInfoUI messageInfoUI) {
        long msgTime = Long.parseLong(messageInfoUI.getMessageInfo().messageTime);
        long current = System.currentTimeMillis() * 1000;
        long interval = current - msgTime;
        return interval < Constants.DEFAULT_CAN_RECALL_INTERVAL && messageInfoUI.getMessageInfo().isSent;
    }

    /**
     * 如果是文字的话才可以复制
     *
     * @param messageInfoUI 消息对象
     * @return 结果
     */
    public static Boolean isCanCopy(MessageInfoUI messageInfoUI) {
        return messageInfoUI.getMessageInfo().messageType == MessageType.TEXT;
    }

    /**
     * 获取长按时候弹框显示的所有操作
     *
     * @param messageInfoUI 消息对象
     * @return 结果
     */
    public static Map<String, Integer> getOperations(MessageInfoUI messageInfoUI) {
        Map<String, Integer> map = new HashMap<>();
        if (isCanRecall(messageInfoUI)) {
            map.put("撤回", Constants.OPERATION_RECALL);
        }
        if (isCanCopy(messageInfoUI)) {
            map.put("复制", Constants.OPERATION_COPY);
        }
        map.put("删除", Constants.OPERATION_DELETE);
        map.put("收藏", Constants.OPERATION_COLLECT);
        map.put("转发", Constants.OPERATION_FORWARD);
        map.put("引用", Constants.OPERATION_QUOTE);
        return map;
    }

    public static void copyToClipboard(Context context, String content) {
        ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
        if (clipboardManager == null) {
            return;
        }
        ClipData clipData = ClipData.newPlainText(AttrConstants.COPY_MESSAGE_OBJECT, content);
        clipboardManager.setPrimaryClip(clipData);
    }

    public static MessageInfo getMessageInfo(MessageModel model, ImSendType imSendType) {
        MessageInfo messageInfo = new MessageInfo();

        messageInfo.isSent = model.isSent;
        messageInfo.messageId = model.messageId;
        messageInfo.messageContent = model.messageContent;
        messageInfo.messageType = model.messageType;
        messageInfo.messageTime = model.messageTime;
        messageInfo.sendStatus = model.sendStatus;
        messageInfo.fileAttrs = model.fileAttrs;
        messageInfo.localPath = model.localPath;
        messageInfo.isRevoke = model.isRevoke;
        messageInfo.messageAttr = model.messageAttr;

        messageInfo.imSendType = imSendType;
        if (model instanceof P2PMessageModel) {
            P2PMessageInfo p2PMessageModel = (P2PMessageInfo) model;
            messageInfo.imMessage = p2PMessageModel.imMessage;
            messageInfo.isRead = p2PMessageModel.isRead;

            messageInfo.senderId = p2PMessageModel.targetId;
            messageInfo.senderName = p2PMessageModel.targetName;
            messageInfo.senderPortrait = messageInfo.isSent ? Constants.userInfo.avatarUrl : p2PMessageModel.targetPortraitUrl;
        } else {
            GroupMessageInfo groupMessageInfo = (GroupMessageInfo) model;
            messageInfo.imMessage = groupMessageInfo.imMessage;
            messageInfo.numOfDistribute = groupMessageInfo.numOfDistribute;
            messageInfo.numOfRead = groupMessageInfo.numOfRead;

            messageInfo.senderId = groupMessageInfo.fromUid;
            messageInfo.senderName = groupMessageInfo.fromName;
            messageInfo.senderPortrait = groupMessageInfo.fromPortraitUrl;
        }
        return messageInfo;
    }


    public static MessageInfo getTextMessageInfo(String content, ImSendType imSendType, String quoteId, String quoteContent) {
        MessageInfo messageInfo = new MessageInfo();

        String messageId = getUUID();
        messageInfo.isSent = true;
        messageInfo.messageId = messageId;
        messageInfo.messageContent = IMUtil.getMessageContent(content, "").toString();
        messageInfo.messageType = MessageType.TEXT;
        messageInfo.messageTime = DateTimeUtil.getTimeStamp();
        messageInfo.sendStatus = SendStatus.SEND_ING;
        messageInfo.isRevoke = false;
        messageInfo.messageAttr = "NORMAL";

        messageInfo.imMessage = new ImTextMessage(content, "", quoteId, quoteContent);
        messageInfo.senderId = Constants.userInfo.userId;
        messageInfo.senderName = Constants.userInfo.nickName;
        messageInfo.senderPortrait = Constants.userInfo.avatarUrl;
        messageInfo.imSendType = imSendType;
        return messageInfo;
    }

    public static MessageInfo getImageMessageInfo(String content, ImSendType imSendType) {
        MessageInfo messageInfo = new MessageInfo();
        try {
            String messageId = getUUID();
            messageInfo.isSent = true;
            messageInfo.messageId = messageId;

            JSONObject j = IMUtil.getMessageContent(content, "");
            IMUtil.getImageAttr(j, content);

            messageInfo.messageContent = j.toString();
            messageInfo.messageType = MessageType.IMAGE;
            messageInfo.messageTime = DateTimeUtil.getTimeStamp();
            messageInfo.sendStatus = SendStatus.SEND_ING;
            messageInfo.isRevoke = false;
            messageInfo.messageAttr = "NORMAL";


            messageInfo.imMessage = new ImImageMessage(content, "", j.optInt("width"), j.optInt("height"), j.optInt("fileSize"));
            messageInfo.senderId = Constants.userInfo.userId;
            messageInfo.senderName = Constants.userInfo.nickName;
            messageInfo.senderPortrait = Constants.userInfo.avatarUrl;
        } catch (Exception e) {
            e.getMessage();
        }
        return messageInfo;
    }

    public static MessageInfo getVideoMessageInfo(String content, ImSendType imSendType) {
        MessageInfo messageInfo = new MessageInfo();
        try {
            String messageId = getUUID();
            messageInfo.isSent = true;
            messageInfo.messageId = messageId;
            JSONObject j = IMUtil.getMessageContent(content, "");
            IMUtil.getVideoAttr(j, content);

            messageInfo.messageContent = j.toString();
            messageInfo.messageType = MessageType.VIDEO;
            messageInfo.messageTime = DateTimeUtil.getTimeStamp();
            messageInfo.sendStatus = SendStatus.SEND_ING;
            messageInfo.isRevoke = false;
            messageInfo.messageAttr = "NORMAL";
            messageInfo.imMessage = new ImVideoMessage(content, "", j.optInt("width"), j.optInt("height"), j.optInt("duration"));
            messageInfo.senderId = Constants.userInfo.userId;
            messageInfo.senderName = Constants.userInfo.nickName;
            messageInfo.senderPortrait = Constants.userInfo.avatarUrl;
        } catch (Exception e) {
            e.getMessage();
        }
        return messageInfo;
    }

    public static MessageInfo getFileMessageInfo(String content, ImSendType imSendType) {
        MessageInfo messageInfo = new MessageInfo();
        try {
            String messageId = getUUID();
            messageInfo.isSent = true;
            messageInfo.messageId = messageId;
            JSONObject j = IMUtil.getMessageContent(content, "");
            IMUtil.getFileAttr(j, content);

            messageInfo.messageContent = j.toString();
            messageInfo.messageType = MessageType.FILE;
            messageInfo.messageTime = DateTimeUtil.getTimeStamp();
            messageInfo.sendStatus = SendStatus.SEND_ING;
            messageInfo.isRevoke = false;
            messageInfo.messageAttr = "NORMAL";
            messageInfo.localPath = content;

            messageInfo.imMessage = new ImFileMessage(content, j.optString("fileName"), j.optInt("fileSize"), "");
            messageInfo.senderId = Constants.userInfo.userId;
            messageInfo.senderName = Constants.userInfo.nickName;
            messageInfo.senderPortrait = Constants.userInfo.avatarUrl;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return messageInfo;
    }

    public static MessageInfo getVoiceMessageInfo(VoiceInfo voiceInfo, ImSendType imSendType) {
        MessageInfo messageInfo = new MessageInfo();
        try {
            String messageId = getUUID();
            messageInfo.isSent = true;
            messageInfo.messageId = messageId;
            JSONObject j = IMUtil.getMessageContent(voiceInfo.getPath(), "");
            IMUtil.getVoiceAttr(j, voiceInfo.getPath());

            messageInfo.messageContent = j.toString();
            messageInfo.messageType = MessageType.VOICE;
            messageInfo.messageTime = DateTimeUtil.getTimeStamp();
            messageInfo.sendStatus = SendStatus.SEND_ING;
            messageInfo.isRevoke = false;
            messageInfo.messageAttr = "NORMAL";
            messageInfo.localPath = voiceInfo.getPath();

            messageInfo.imMessage = new ImAudioMessage(voiceInfo.getPath(), voiceInfo.getDuration(), j.optString("fileName"), "");
            messageInfo.senderId = Constants.userInfo.userId;
            messageInfo.senderName = Constants.userInfo.nickName;
            messageInfo.senderPortrait = Constants.userInfo.avatarUrl;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return messageInfo;
    }


    public static MessageInfo getSequenceMessageInfo(SequenceInfo sequenceInfo, ImSendType imSendType) {
        MessageInfo messageInfo = new MessageInfo();
        try {
            String messageId = getUUID();
            messageInfo.isSent = true;
            messageInfo.messageId = messageId;

            JSONObject extraParams = new JSONObject();
            extraParams.put("sequenceId", sequenceInfo.sequenceId);
            extraParams.put("fromUserId", sequenceInfo.fromUserId);
            extraParams.put("fromUserName", sequenceInfo.fromUserName);
            extraParams.put("fromGroupId", sequenceInfo.fromGroupId);
            extraParams.put("remark", sequenceInfo.remark);
            extraParams.put("participants", new JSONArray(sequenceInfo.participants));

            JSONObject j = IMUtil.getMessageContent(sequenceInfo.sequenceContent, extraParams.toString());

            messageInfo.messageContent = j.toString();
            messageInfo.messageType = MessageType.SEQUENCE;
            messageInfo.messageTime = DateTimeUtil.getTimeStamp();
            messageInfo.sendStatus = SendStatus.SEND_ING;
            messageInfo.isRevoke = false;
            messageInfo.messageAttr = "NORMAL";

            messageInfo.imMessage = new ImSequenceMessage(sequenceInfo.sequenceContent, extraParams.toString());
            messageInfo.senderId = Constants.userInfo.userId;
            messageInfo.senderName = Constants.userInfo.nickName;
            messageInfo.senderPortrait = Constants.userInfo.avatarUrl;
        } catch (Exception e) {
            e.getMessage();
        }
        return messageInfo;
    }

    public static MessageInfo getCardMessageInfo(CardInfo cardInfo, String staffId, String profile, String theme, ImSendType imSendType) {
        MessageInfo messageInfo = new MessageInfo();
        try {
            String messageId = getUUID();
            messageInfo.isSent = true;
            messageInfo.messageId = messageId;

            JSONObject extraParams = new JSONObject();
            extraParams.put("type", "person");
            extraParams.put("staffId", "1111111");
            extraParams.put("name", cardInfo.friendInfoUI.nickName);
            extraParams.put("avatar", cardInfo.friendInfoUI.protraitUrl);
            extraParams.put("departmentName", cardInfo.friendInfoUI.department);
            extraParams.put("profile", "2222222222222222");
            extraParams.put("url", cardInfo.ticket);
            extraParams.put("theme", "333333333333333");


            String content = cardInfo.friendInfoUI.nickName + "的名片";
            JSONObject j = IMUtil.getMessageContent(content, extraParams.toString());

            messageInfo.messageContent = j.toString();
            messageInfo.messageType = MessageType.CARD;
            messageInfo.messageTime = DateTimeUtil.getTimeStamp();
            messageInfo.sendStatus = SendStatus.SEND_ING;
            messageInfo.isRevoke = false;
            messageInfo.messageAttr = "NORMAL";

            messageInfo.imMessage = new ImSequenceMessage(content, extraParams.toString());
            messageInfo.senderId = Constants.userInfo.userId;
            messageInfo.senderName = Constants.userInfo.nickName;
            messageInfo.senderPortrait = Constants.userInfo.avatarUrl;
        } catch (Exception e) {
            e.getMessage();
        }
        return messageInfo;
    }

    public static String getGroupMemberDisplayName(GroupMemberInfo userInfo) {
        if (!TextUtils.isEmpty(userInfo.nickNameInGroup)) {
            return userInfo.nickNameInGroup;
        } else {
            return userInfo.nickName;
        }
    }

    public static ImMessage getImMessage(MessageType messageType, String content) throws JSONException {
        if (messageType == MessageType.IMAGE) {
            JSONObject j = new JSONObject(content);
            return new ImImageMessage(j.optString("msgContent"), j.optInt("width"), j.optInt("height"), j.optString("thumb"), j.optString("fileName"), j.optInt("fileSize"), "");
        } else if (messageType == MessageType.VOICE) {
            JSONObject j = new JSONObject(content);
            return new ImAudioMessage(j.optString("msgContent"), j.optInt("duration"), j.optString("fileName"), "");
        } else if (messageType == MessageType.VIDEO) {
            JSONObject j = new JSONObject(content);
            return new ImVideoMessage(j.optString("msgContent"), j.optInt("width"), j.optInt("height"), j.optString("thumb"), j.optString("fileName"), j.optInt("duration"), "");
        } else if (messageType == MessageType.FILE) {
            JSONObject j = new JSONObject(content);
            return new ImFileMessage(j.optString("msgContent"), j.optString("fileName"), j.optInt("fileSize"), "");
        } else {
            JSONObject j = new JSONObject(content);
            return new ImTextMessage(j.optString("msgContent"), "", j.optString("quoteId"), j.optString("quoteContent"));
        }
    }


    public static String getQuoteInfo(MessageInfoUI uiMessage) {
        if (uiMessage.getMessageInfo().messageType == MessageType.IMAGE) {
            return uiMessage.getMessageInfo().senderName + ":[图片]";
        } else if (uiMessage.getMessageInfo().messageType == MessageType.VOICE) {
            return uiMessage.getMessageInfo().senderName + ":[语言]";
        } else if (uiMessage.getMessageInfo().messageType == MessageType.VIDEO) {
            return uiMessage.getMessageInfo().senderName + ":[视频]";
        } else if (uiMessage.getMessageInfo().messageType == MessageType.FILE) {
            return uiMessage.getMessageInfo().senderName + ":[文件]";
        } else if (uiMessage.getMessageInfo().messageType == MessageType.LOCATION) {
            return uiMessage.getMessageInfo().senderName + ":[位置]";
        } else if (uiMessage.getMessageInfo().messageType == MessageType.CARD) {
            return uiMessage.getMessageInfo().senderName + ":[卡片]";
        } else {
            try {
                JSONObject j = new JSONObject(uiMessage.getMessageInfo().messageContent);
                String msgContent = j.getString("msgContent");
                if (msgContent.length() > 48) {
                    msgContent = msgContent.substring(0, 48);
                }
                return uiMessage.getMessageInfo().senderName + ":" + msgContent;
            } catch (Exception e) {
                return "";
            }
        }
    }

    public static String getQuoteContent(MessageInfoUI uiMessage) {
        if (uiMessage.getMessageInfo().messageType == MessageType.IMAGE) {
            return "[图片]";
        } else if (uiMessage.getMessageInfo().messageType == MessageType.VOICE) {
            return "[语言]";
        } else if (uiMessage.getMessageInfo().messageType == MessageType.VIDEO) {
            return "[视频]";
        } else if (uiMessage.getMessageInfo().messageType == MessageType.FILE) {
            return "[文件]";
        } else if (uiMessage.getMessageInfo().messageType == MessageType.LOCATION) {
            return "[位置]";
        } else if (uiMessage.getMessageInfo().messageType == MessageType.CARD) {
            return "[卡片]";
        } else {
            try {
                JSONObject j = new JSONObject(uiMessage.getMessageInfo().messageContent);
                return j.getString("msgContent");
            } catch (Exception e) {
                return "";
            }
        }
    }
    //===================================================================

    /**
     * @param listener
     */
    public static void addOnConversationListRefreshListener(OnConversationListRefreshListener listener) {
        if (listener == null) {
            return;
        }
        onConversationListRefreshListenerList.add(listener);
    }

    /**
     * 删除消息监听
     *
     * @param listener
     */
    public static void removeOnConversationListRefreshListener(OnConversationListRefreshListener listener) {
        if (listener == null) {
            return;
        }
        onConversationListRefreshListenerList.remove(listener);
    }

    /**
     * @param listener
     */
    public static void addOnConversationRefreshListener(OnConversationRefreshListener listener) {
        if (listener == null) {
            return;
        }
        onConversationRefreshListeners.add(listener);
    }

    /**
     * 删除消息监听
     *
     * @param listener
     */
    public static void removeOnConversationRefreshListener(OnConversationRefreshListener listener) {
        if (listener == null) {
            return;
        }
        onConversationRefreshListeners.remove(listener);
    }


    /**
     * @param listener
     */
    public static void addOnConversationInfoUpdateListener(OnConversationInfoUpdateListener listener) {
        if (listener == null) {
            return;
        }
        onConversationInfoUpdateListeners.add(listener);
    }

    /**
     * 删除消息监听
     *
     * @param listener
     */
    public static void removeOnConversationInfoUpdateListener(OnConversationInfoUpdateListener listener) {
        if (listener == null) {
            return;
        }
        onConversationInfoUpdateListeners.remove(listener);
    }

    //===================================================================
    //刷新会话列表
    public static void fireConversationListRefreshEvent() {
        for (OnConversationListRefreshListener imRcvMsgListener : onConversationListRefreshListenerList) {
            imRcvMsgListener.refreshConversationList();
        }
    }

    //刷新单个会话
    public static void fireConversationRefreshEvent() {
        for (OnConversationRefreshListener imRcvMsgListener : onConversationRefreshListeners) {
            imRcvMsgListener.refreshConversation();
        }
    }

    /**
     * 清除指定会话的未读状态
     */
    public static void clearUnreadStatus() {
        for (OnConversationInfoUpdateListener listener : onConversationInfoUpdateListeners) {
            listener.onConversationUnreadClear();
        }
    }

    /**
     * 会话免打扰
     */
    public static void setConversationSlient() {
        for (OnConversationInfoUpdateListener listener : onConversationInfoUpdateListeners) {
            listener.onConversationSilentUpdate();
        }
    }

    /**
     * 设置草稿
     */
    public static void setConversationDraft() {
        for (OnConversationInfoUpdateListener listener : onConversationInfoUpdateListeners) {
            listener.onConversationDraftUpdate();
        }
    }
}
